package edu.ynu.se.xiecheng.achitectureclass.auth.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ynu.se.xiecheng.achitectureclass.auth.token.BearerToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class CustomAuthenticationFilter extends FormAuthenticationFilter {
    
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String uri = httpRequest.getRequestURI();
        
        // 对于 OPTIONS 请求直接放行
        if (httpRequest.getMethod().equals(HttpMethod.OPTIONS.name())) {
            return true;
        }
        
        // 对于登录接口直接放行
        if (uri.equals("/api/auth/login") || 
            uri.equals("/api/auth/logout") || 
            uri.equals("/api/auth/register")) {
            return true;
        }
        
        // 对于文档相关的请求直接放行
        if (uri.contains("/doc.html") || 
            uri.contains("/swagger") || 
            uri.contains("/api-docs") || 
            uri.contains("/webjars") ||
            uri.contains("/configuration") ||
            uri.equals("/") ||
            uri.equals("/error") ||
            uri.contains("/favicon.ico")) {
            return true;
        }
        
        // 检查认证头
        String authHeader = httpRequest.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            try {
                Subject subject = SecurityUtils.getSubject();
                if (!subject.isAuthenticated()) {
                    // 如果当前未认证，尝试使用token认证
                    subject.login(new BearerToken(token));
                }
                return true;
            } catch (Exception e) {
                return false;
            }
        }
        
        return false;
    }
    
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        
        // 添加跨域响应头
        String origin = httpRequest.getHeader("Origin");
        httpResponse.setHeader("Access-Control-Allow-Origin", origin);
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
        httpResponse.setHeader("Access-Control-Allow-Headers", "*");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Max-Age", "3600");
        
        httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        httpResponse.setContentType("application/json;charset=utf-8");
        
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "请先登录");
        result.put("error", "未认证");
        
        try (PrintWriter out = httpResponse.getWriter()) {
            ObjectMapper mapper = new ObjectMapper();
            out.write(mapper.writeValueAsString(result));
        }
        
        return false;
    }
} 